﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using SimpleRest.Core.Routing;
using SimpleRest.Core.Routing;
using SimpleRest.Core;
using SimpleRest.WebTest.Entities;
using SimpleRest.Core.Extensions.Documentation;

namespace SimpleRest.WebTest.Services
{
    // This attribute indicates to the SimpleRest platform that this class is a service. Because a version was specified and IgnoreServicePrefix was not set
    // the service route registered for this service will be prefixed with /v1.
    [GeneralDescription("Demo service used to interact with review resource objects.")]
    [LinkDescription("https://blog.apigee.com/detail/restful_api_design", Description = "Apigee.com.  Teach a dog to rest!")]
    [StatusCodeDescription(StatusCode = System.Net.HttpStatusCode.OK, Description = "Indicates that a request was processed successfully.")]
    [Service("reviews", 1)]
    public class ReviewsService : ServiceBase
    {
        private static List<Review> Items = new List<Review>()
        {
            Review.GetMock("0"),
            Review.GetMock("1"),
            Review.GetMock("2"),
            Review.GetMock("3"),
            Review.GetMock("4"),
            Review.GetMock("5"),
            Review.GetMock("6"),
            Review.GetMock("7"),
            Review.GetMock("8"),
            Review.GetMock("9"),
            Review.GetMock("10"),
            Review.GetMock("11"),
            Review.GetMock("12"),
            Review.GetMock("13"),
            Review.GetMock("14"),
            Review.GetMock("15"),
            Review.GetMock("16"),
            Review.GetMock("17"),
            Review.GetMock("18"),
            Review.GetMock("19"),
        };

        [GeneralDescription("Return a list of review resources.")]
        [StatusCodeDescription(StatusCode = System.Net.HttpStatusCode.OK, Description="Successfully returned list of review resources.")]
        [ParameterDescription("entityId", typeof(string), true, Description = "Additional id information related to the entity you are targeting.")]
        [ParameterDescription("min", typeof(uint), true, Description = "Indicates a minimum number of resources to return.")]
        [ParameterDescription("max", typeof(uint), true, Description = "Indicates a maximum number of resources to return.")]
        [ParameterDescription("userId", typeof(string), true, Description = "The user id in which all resources returned should be associated to.")]
        [ParameterDescription("startDt", typeof(DateTime), true, Description = "The time in which all resources returned should be greater than or equal to.")]
        [ParameterDescription("endDt", typeof(DateTime), true, Description = "The time in which all resources returned should be less than or equal to.")]
        [WebGet(UriTemplate = "?entity_id={entityId}&min={min}&max={max}&user_id={userId}&sort={sort}&startdt={startDt}&enddt={endDt}")]
        public OperationResponse<List<Review>> GetAll(string entityId, int min, int max, string userId, string sort, DateTime startDt, DateTime endDt)
        {
            return new OperationResponse<List<Review>>(Items);
        }

        [GeneralDescription("Return a review resource associated to the id indicated in the URI")]
        [StatusCodeDescription(StatusCode = System.Net.HttpStatusCode.OK, Description = "Request was successful and a resource should be returned.")]
        [StatusCodeDescription(StatusCode = System.Net.HttpStatusCode.NotFound, Description = "The requested resource was not found or does not exist.")]
        [ParameterDescription("id", typeof(string), false, Description = "The review resource id in which you wish to return.")]
        [WebGet(UriTemplate = "{id}")]
        public OperationResponse<Review> Get(int id)
        {
            var item = Items.FirstOrDefault(d => d.Id == id.ToString());
            if (item == null)
                return new OperationResponse<Review>( System.Net.HttpStatusCode.NotFound);
            return new OperationResponse<Review>(item);
        }

        /// <summary>
        /// Hi this is commented
        /// </summary>
        /// <param name="review"></param>
        /// <returns></returns>
        [GeneralDescription("Create a review resource object using parameters specified in the http content body.  Returns the id upon successful creation.")]
        [StatusCodeDescription(StatusCode = System.Net.HttpStatusCode.Created, Description = "Resource was created successfully and you should expect an id in the response body.")]
        [WebPost(UriTemplate = "")]
        public OperationResponse<string> Create([HttpBody]Review review)
        {
            review.Id = Guid.NewGuid().ToString();
            Items.Add(review);
            return new OperationResponse<string>(review.Id, System.Net.HttpStatusCode.Created);
        }

        [GeneralDescription("Delete a review resource associated to the ID specified in the URI.")]
        [ParameterDescription("id", typeof(string), false, Description = "Indicates which review resource you would like to delete.")]
        [StatusCodeDescription(StatusCode = System.Net.HttpStatusCode.OK, Description = "Successfuly deleted.")]
        [WebDelete(UriTemplate = "{id}")]
        public OperationResponse Delete(string id)
        {
            var item = Items.FirstOrDefault(d => d.Id == id);
            if (item == null)
                return new OperationResponse(System.Net.HttpStatusCode.NotImplemented);

            Items.Remove(item);
            return new OperationResponse(System.Net.HttpStatusCode.OK);
        }

        [GeneralDescription("Update review associated to id specified in the URI.")]
        [ParameterDescription("id", typeof(string), false, Description = "The id for the associated review that you wish to update.")]
        [StatusCodeDescription(StatusCode = System.Net.HttpStatusCode.OK, Description = "Indicates that the update was successful.")]
        [StatusCodeDescription(StatusCode = System.Net.HttpStatusCode.NotFound, Description = "Indicates that the review you are attempting to update does not exist")]
        [WebPut(UriTemplate = "{id}")]
        public OperationResponse Update([HttpBody]Review review, string id)
        {
            var item = Items.FirstOrDefault(d => d.Id == id);
            if (item == null)
                return new OperationResponse(System.Net.HttpStatusCode.NotFound);

            review.Id = id;
            Items.Remove(item);
            Items.Add(review);
            return new OperationResponse(System.Net.HttpStatusCode.OK);
        }
    }
}